package buscaminas;

import buscaminas.Tiempo;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Buscaminas extends JFrame implements ActionListener {

    /*Definimos loa atributos*/
    JButton[][] botones; /*Arreglo para los botones*/
    int [][] minas; /*Arreglo para las minas*/

    /*Creación de cajas de texto*/
    JTextField txtTime = new JTextField(3);
    JTextField txtMinas = new JTextField(3);

    /*Creación de etiquetas*/
    JLabel time = new JLabel("Tiempo: ");
    JLabel minasRestantes = new JLabel("Minas restantes: ");

    /*Estos valores los dará el usuario*/
    int numeroBotones;
    int numeroMinas;

    int total=numeroBotones*numeroBotones-numeroMinas;

    /*t será de tipo Tiempo (Clase)*/
    Tiempo t;
    
    /*Constructor*/
    Buscaminas(){
        super("Entrada"); /*Llama al constructor de JFrame y le pone un nombre*/
        
        /*Convierte una cadena en números*/
        numeroBotones = Integer.parseInt(JOptionPane.showInputDialog("Longitud lateral: ")); /*Convierte una cadena en números*/
        numeroMinas = Integer.parseInt(JOptionPane.showInputDialog("Número de Minas: "));

        /*Si el número de minas ingresado es mayor al número de casillas
         se mostrará un mensaje de error y se deberán introducir
         los datos de nuevo*/
        if(numeroMinas>numeroBotones*numeroBotones){
            JOptionPane.showMessageDialog(this, "El número de minas debe ser menor al número de casillas");
            new Buscaminas();
        }

        /*Mensaje para iniciar el juego y el tiempo*/
        JOptionPane.showMessageDialog(this, "De click en el botón Aceptar para iniciar el juego");


        botones = new JButton[numeroBotones][numeroBotones];
        minas = new int [numeroBotones][numeroBotones];

        /*Panel Norte*/
        JPanel panelNorth = new JPanel();
        panelNorth.add(minasRestantes);
	panelNorth.add(txtMinas);
        panelNorth.add(time);
        panelNorth.add(txtTime);

        add(panelNorth,"North");
        txtMinas.setEditable(false);
	txtTime.setEditable(false);
        txtMinas.setText(Integer.toString(total));

        /*Panel Central, donde estarán los botones*/
        JPanel panelCenter = new JPanel(new GridLayout(numeroBotones,numeroBotones));

        /*Creamos y colocamos los botones*/
        for(int i = 0; i<numeroBotones ; i++)
	   for(int j = 0; j<numeroBotones ; j++)
               {
		/*Creamos un botón*/
		botones [i][j] = new JButton();
		/*Agregamos a nuestro panel central*/
		panelCenter.add(botones[i][j]);
		/*ActionListener*/
		botones[i][j].addActionListener(this);
				}
		this.add(panelCenter,"Center");
		/*Metodo que coloca el número de minas que ingresa el usuario*/
                colocar(numeroMinas);

                /*Arranca el tiempo*/
                t = new Tiempo(this);
                t.start();


                 /*Características de la ventana*/
                 setDefaultCloseOperation(EXIT_ON_CLOSE);
                 setTitle("Buscaminas");
                 setResizable(false);
                 setSize(600,600);
                 setVisible(true);
	}

        /*Método que coloca las minas aleatorias en el tablero*/
        void colocar(int numMinas)
	{
		System.out.println("Colocando Minas... \n");
		for(int i = 0; i<numMinas ;i++)
		{

		/*Coordenadas*/
		int x,y = 0;
		double w,z = 0;

		/*	1 Existe Mina
		 *	0 No existe Mina
		 */
			/*Se colocan las minas aleatoriamente*/
			do
			{
                        /*Posiciones aleatorias*/
                         w = Math.random()*numeroBotones;
		 	 z = Math.random()*numeroBotones;
		 	 x = (int)w;
		 	 y = (int)z;
			}
			while(minas[x][y]!=0);
			/* 1 significa que ponemos una mina*/
                        minas[x][y]=1;
		}

               /* Para poder visualizar el tablero dentro de NetBeans
                y verificar que las minas están en 1*/
                 for(int i = 0; i<numeroBotones ; i++)
                  {
	  	System.out.println();
	  	for(int j = 0; j<numeroBotones ; j++)
	  		System.out.print(" " + minas[i][j]);
	  }

	}

    public void actionPerformed(ActionEvent e) {
        /*Aquí ponemos la acción que se realizará*/
        for(int i = 0; i<numeroBotones ;i++)
	   for(int j = 0; j<numeroBotones ;j++){
	       if(e.getSource() == botones[i][j] && botones[i][j].getBackground()!= Color.WHITE)
				{ 
				botones[i][j].setBackground(Color.WHITE);
                                if(minas[i][j]==1){
                                bomba();
                                }
                                else
                                {
                                casillaNull(i,j);
                                }
			}
		}
	}

    /*Método que se ejecutará cuando se presione un botón sin mina*/
    void casillaNull(int i, int j){
                total--;
		txtMinas.setText(Integer.toString(total));
                botones[i][j].setText(Integer.toString(minasCerca(i,j))); //Cuantas Minas cerca
                
                if(total == 0)
        	winner();
	}

    /*Se manda llamar cuando un juego termina (Si no queremos que se ejecute un nuevo juego
     sólo hay que quitar el llamado a este método*/
    void nuevoJuego()
	{
        for(int i = 0; i<numeroBotones ; i++)
            for(int j=0 ; j<numeroBotones ; j++)
		{
		minas[i][j] = 0;
		botones[i][j].setText("");
		botones[i][j].setBackground(null);
		}
		colocar(numeroMinas);
		total = numeroBotones*numeroBotones-numeroMinas;
		txtMinas.setText(Integer.toString(total));
		t = new Tiempo(this);
                t.start();
	}

        /*Método que se ejecuta cuando un Jugaro gana*/
        void winner()
	{
		/*Paramos el tiempo*/
		t.stop();
		JOptionPane.showMessageDialog(this,"Has ganado. \nTu tiempo fue de: " + txtTime.getText() + " segundos");
		nuevoJuego();
	}

        /*Método de perdedor, cuando da clic en una bomba*/
	void bomba()
	{
	t.stop(); 

        for(int i = 0 ; i<numeroBotones ; i++)
		for(int j=0 ; j<numeroBotones ; j++)
		{
		if(minas[i][j] == 1)
			{
                        botones[i][j].setBackground(Color.RED);
			}
		}
		JOptionPane.showMessageDialog(this,"Lo siento... Has perdido!");
                nuevoJuego();
                
	}

        /*Método que devuelve el número de minas cerca*/
        int minasCerca(int x,int y)
	{
			/*
			 *	x-filas
			 *	y-columnas
			 */

            int minCerca=0;
            for(int i = y-1 ; i<= y+1; i++){

                /*Horizontal*/
                if(i>-1 && i<numeroBotones){
	                if(minas[x][i] == 1){
	             		minCerca++;
    	                }
                }
            }
            	/*Vertical*/
                for(int j= x-1 ; j<=x+1; j++){
	                		if(j>-1 && j<numeroBotones)
	                			if(minas[j][y] == 1){
	                			minCerca++;
	                			}
	                	}
	        
                /*Diagonales*/

	        /*Esquina superior izquierda*/
	        int w = x;
	        int z = y;
	        w--;
	        z--;
	        	for(int i=w; i<w+3 ; i++)
	        		{
	        			if(i>-1 && i<numeroBotones && z>-1 && z<numeroBotones)
	        			 if(minas[i][z] == 1){
	             		minCerca++;
	                	}
	                	z++;
	        		}

                /*Esquina superior izquierda*/
	        w = x;
	        z = y;
	        w--;
	        z++;
	        	for(int i = w ; i<w+3 ; i++)
	        		{
	        			if(i>-1 && i<numeroBotones && z>-1 && z<numeroBotones)
	        			 if(minas[i][z] == 1){
	             		minCerca++;
	                	}
	                	z--;
	        		}
            return minCerca;
	}

        /*Main*/
        public static void main(String[] args) {
            Buscaminas joe = new Buscaminas();
    }
}


